package org.wangjie.analysisRSSI.controller.v1;

import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.wangjie.analysisRSSI.model.data.MaxAndMean;
import org.wangjie.analysisRSSI.model.entity.SnifferdataEntity;
import org.wangjie.analysisRSSI.model.vo.NodeInfo;
import org.wangjie.analysisRSSI.model.vo.SinfferDataVO;
import org.wangjie.analysisRSSI.model.vo.SystemInfo;
import org.wangjie.analysisRSSI.service.SnifferdataService;

import java.io.Serializable;
import java.util.*;

/**
 * (Snifferdata)表控制层
 *
 * @author Cheney Han
 * @since 2021-03-05 11:59:08
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/v1/snifferdata")
public class SnifferdataController extends ApiController {
    /**
     * 服务对象
     */
    @Autowired
    private SnifferdataService snifferdataService;

    /**
     * 查询所有数据
     * @return
     */
    @GetMapping("/selectAll")
    public Object selectAll() {
//        ArrayList<SinfferDataVO> sinfferDataVOS = new ArrayList<>();
//        List<SnifferdataEntity> snifferdataEntities = this.snifferdataService.list();
//        int sum = 0;
//        int sumLQI = 0;
//        for(SnifferdataEntity snifferdataEntity : snifferdataEntities){
//            SinfferDataVO sinfferDataVO = new SinfferDataVO();
//            sinfferDataVO.setSeqnuminpsdfile(snifferdataEntity.getSeqnuminpsdfile());
//            sinfferDataVO.setLength(snifferdataEntity.getLength());
//            String fcf = snifferdataEntity.getFcf();
//            String type = "";
//            switch (fcf){
//                case "0x8841":
//                    type = "DATA";
//                    break;
//                case "0x8861":
//                    type = "DATA";
//                    break;
//                case "0x0002":
//                    type = "ACK";
//                    break;
//                default:
//                    type = "ERROR";
//                    break;
//            }
//            sinfferDataVO.setType(type);
//            sinfferDataVO.setDsn(snifferdataEntity.getDsn());
//            sinfferDataVO.setDestpan(snifferdataEntity.getDestpan());
//            sinfferDataVO.setDestaddress(snifferdataEntity.getDestaddress());
//            sinfferDataVO.setSrcaddress(snifferdataEntity.getSrcaddress());
//            sinfferDataVO.setPayload(snifferdataEntity.getPayload());
//            int fcs = Integer.parseInt(snifferdataEntity.getFcs().substring(4), 16);
//            int LQI = Integer.parseInt(snifferdataEntity.getFcs().substring(2, 4), 16) & 0x7F;
//            sumLQI += LQI;
//            int RSSI = fcs > 128 ? fcs - 256 - 73 : fcs - 73;
//            sinfferDataVO.setRSSI(Integer.toString(RSSI));
//            sum += RSSI;
//            sinfferDataVOS.add(sinfferDataVO);
//        }
//        HashMap<String, Object> systemIndicator = new HashMap<>();
//        systemIndicator.put("size", sinfferDataVOS.size());
//        systemIndicator.put("meanRSSI", (float)sum/sinfferDataVOS.size());
//        systemIndicator.put("meanLQI", (float)sumLQI/sinfferDataVOS.size());
        HashMap<String, Integer> result = new HashMap<>();
        result.put("size", this.snifferdataService.list().size());
        return success(result);
    }

    /**
     * 分页查询所有数据
     *
     * @param pageNumber 分页序号
     * @param pageSize 分页数量
     * @return 所有数据
     */
    @GetMapping("/pageLimit")
    public Object selectByPage(@RequestParam("pageNumber") int pageNumber, @RequestParam("pageSize") int pageSize) {
        List<SinfferDataVO> sinfferDataVOS = snifferdataService.selectByPage(pageNumber, pageSize);
        return success(sinfferDataVOS);
    }

    @GetMapping("/packetLoss")
    public Object Packetloss(){
        int numberOf255 = snifferdataService.selectNumberBy255();
        int dsn0 = snifferdataService.selectLastRecordBySrcAddress("0x0000").getDsn();
        int dsn1 = snifferdataService.selectLastRecordBySrcAddress("0x0001").getDsn();
        int dsn2 = snifferdataService.selectLastRecordBySrcAddress("0x0002").getDsn();
        int dsn3 = snifferdataService.selectLastRecordBySrcAddress("0x0003").getDsn();
        int totalNumberOfReceive = snifferdataService.countAllSnifferdataEntities();
        int totalNumberOfSend = numberOf255 * 255 + dsn0 + dsn1 + dsn2 + dsn3;
        int packetloss = totalNumberOfSend - totalNumberOfReceive;
        System.out.println("packetloss = " + packetloss);
        float packetlossRate = (float)packetloss / (float) totalNumberOfSend;
        System.out.println("packetlossRate = " + packetlossRate);
        float ETX = 1/(packetlossRate);
        System.out.println("ETX = " + ETX);
        HashMap<String, String> stringStringHashMap = new HashMap<>();
        stringStringHashMap.put("dropCnt", String.valueOf(packetloss));
        stringStringHashMap.put("dropRate", String.valueOf(packetlossRate));
        stringStringHashMap.put("ETX", String.valueOf(ETX));
        return success(stringStringHashMap);
    }

    @GetMapping("/countAllSnifferByDestPan")
    public Object countAllSnifferByDestPan(){
        return snifferdataService.countAllSnifferByDestPan();
    }

    @GetMapping("/selectTHL")
    public Object selectTHL(){
        List<SnifferdataEntity> snifferdataEntities = snifferdataService.selectTHL("0x0001");
        int maxValue = Integer.MIN_VALUE;
        int sumValue = 0;
        for (int i = 0; i < snifferdataEntities.size(); ++i) {
            if(snifferdataEntities.get(i).getFcs().charAt(2) - '8' < 0){
                snifferdataEntities.remove(i);
            }else{
                sumValue += Integer.parseInt(snifferdataEntities.get(i).getPayload().substring(6,8),16);
                maxValue = Math.max(maxValue, Integer.parseInt(snifferdataEntities.get(i).getPayload().substring(6,8),16));
            }
        }
//        System.out.println("MaxValue : " + (maxValue + 1));
        int size = snifferdataEntities.size();
        float meanVaue = (float)sumValue/(float)size + 1;
//        System.out.println("meanVaue = " + String.format("%.2f",meanVaue));
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("maxValue", String.valueOf(maxValue + 1));
        hashMap.put("meanValue", String.format("%.2f",meanVaue));
        return success(hashMap);
    }

    @GetMapping("/selectByOriginalAddress")
    public Object selectByOriginalAddress(@Param("originalAddress") String originalAddress){
        List<SnifferdataEntity> snifferdataEntities = snifferdataService.selectTHL("0x0001");
        HashMap<String, MaxAndMean> stringIntegerHashMap = new HashMap<>();
        for (SnifferdataEntity snifferdataEntity : snifferdataEntities) {
            String originAddress = snifferdataEntity.getPayload().substring(12, 16);
            if(stringIntegerHashMap.containsKey(originAddress)){
                int hopCount = Integer.parseInt(snifferdataEntity.getPayload().substring(6, 8), 16);
                System.out.println("hopCount = " + hopCount);
                MaxAndMean maxAndMean = stringIntegerHashMap.get(originAddress);
                maxAndMean.setMax(Math.max(hopCount + 1, maxAndMean.getMax()));
                maxAndMean.setSize(maxAndMean.getSize() + 1);
                maxAndMean.setSum(maxAndMean.getSum() + hopCount);
                maxAndMean.setMeanValue((float)maxAndMean.getSum()/(float)maxAndMean.getSize() + 1);
            }else{
                int hopCount = Integer.parseInt(snifferdataEntity.getPayload().substring(6, 8), 16);
                System.out.println("hopCount = " + hopCount);
                MaxAndMean maxAndMean = new MaxAndMean();
                maxAndMean.setMax(Math.max(hopCount + 1, maxAndMean.getMax()));
                maxAndMean.setSize(maxAndMean.getSize() + 1);
                maxAndMean.setSum(maxAndMean.getSum() + hopCount);
                maxAndMean.setMeanValue((float)maxAndMean.getSum()/(float)maxAndMean.getSize() + 1);
                stringIntegerHashMap.put(originAddress, maxAndMean);
            }
        }
        return success(stringIntegerHashMap.get(originalAddress));
    }

    @GetMapping("/nodes")
    public Object nodes(){
        List<SnifferdataEntity> snifferdataEntities = snifferdataService.selectTHL("0x0001");
        HashSet<String> nodes = new HashSet<>();
        for(SnifferdataEntity snifferdataEntity : snifferdataEntities){
            String substring = snifferdataEntity.getPayload().substring(12, 16);
            if(!nodes.contains(substring)){
                nodes.add(substring);
            }
        }
        return success(nodes);
    }

    @GetMapping("/selectByNode")
    public Object selectByNode(@Param("node") String node){
        List<SnifferdataEntity> snifferdataEntities = snifferdataService.selectByNode(node);
        return success(snifferdataEntities);
    }

    @GetMapping("/systemInfo")
    public Object systemInfo(@Param("srcAddress") Integer srcAddress){
        SystemInfo systemInfo = this.snifferdataService.calcSysetmIndicator(srcAddress);
        return success(systemInfo);
    }

    @GetMapping("/nodeInfo")
    public Object nodeInfo(@Param("node")String node){
        NodeInfo nodeInfo = this.snifferdataService.calcNodeInfo(node);
        return success(nodeInfo);
    }
}